﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Web;

namespace EAIClassLibrary
{
    public class MessageFactory
    {

        /// <summary>
        /// Receive a message, and initial its other element, such as msgid, corrid etc.
        /// </summary>
        /// <param name="sourceXml"></param>
        /// <returns></returns>
        public static XmlDocument AddESBHeader(XmlDocument sourceXml)
        {
            var esbEnvelope = ESBEnvelopeEntity.FromXML(sourceXml);

            esbEnvelope.ESBHdVer = "20120608_1.1";
            esbEnvelope.SrvDate = DateTime.Now.ToString("yyyy-MM-dd");
            esbEnvelope.SrvTime = DateTime.Now.ToString("hh:mm:ss.ms");
            esbEnvelope.SrvOpVer = "20120606_1.1";
            esbEnvelope.MsgID = Guid.NewGuid().ToString();
            esbEnvelope.CorrID = Guid.NewGuid().ToString();
            esbEnvelope.ESBRspCode = "0";
            esbEnvelope.ESBRspDec = "Success";

            return esbEnvelope.ToXml();
        }

        /// <summary>
        /// Add esbheader for LA
        /// </summary>
        /// <param name="laxml"></param>
        /// <returns></returns>
        public static XmlDocument AddESBHeaderForLA(XmlDocument laxml, XmlDocument requestXml)
        {
            var requestEnvelope = ESBEnvelopeEntity.FromXML(requestXml);
            var esbEnvelope = new ESBEnvelopeEntity();

            esbEnvelope.ESBHdVer = "20120608_1.1";
            esbEnvelope.SrvDate = DateTime.Now.ToString("yyyy-MM-dd");
            esbEnvelope.SrvTime = DateTime.Now.ToString("hh:mm:ss.ms");
            esbEnvelope.SrvOpVer = "20120606_1.1";
            esbEnvelope.SenderID = requestEnvelope.ReceiverID;
            esbEnvelope.ReceiverID = requestEnvelope.SenderID;
            esbEnvelope.SrvOpName = requestEnvelope.SrvOpName;
            esbEnvelope.MsgID = Guid.NewGuid().ToString();
            esbEnvelope.CorrID = requestEnvelope.CorrID;
            esbEnvelope.ESBRspCode = "0";
            esbEnvelope.ESBRspDec = "Success";

            esbEnvelope.MsgBody = laxml.OuterXml;

            return esbEnvelope.ToXml();
        }

        /// <summary>
        /// Modify esbHeader for AURA Service
        /// </summary>
        /// <param name="laxml"></param>
        /// <param name="requestXml"></param>
        /// <returns></returns>
        public static XmlDocument AddESBHeaderForAURA(XmlDocument auraXml, XmlDocument requestXml)
        {
            var requestEnvelope = ESBEnvelopeEntity.FromXML(requestXml);
            var esbEnvelope = ESBEnvelopeEntity.FromXML(auraXml);
            ModifyResponseHeader(requestXml, esbEnvelope);

            esbEnvelope.ESBHdVer = "20120608_1.1";
            esbEnvelope.SrvDate = DateTime.Now.ToString("yyyy-MM-dd");
            esbEnvelope.SrvTime = DateTime.Now.ToString("hh:mm:ss.ms");
            esbEnvelope.SrvOpVer = "20120606_1.1";
            esbEnvelope.MsgID = Guid.NewGuid().ToString();
            esbEnvelope.ESBRspCode = "0";
            esbEnvelope.ESBRspDec = "Success";
            return esbEnvelope.ToXml();
        }

        /// <summary>
        /// Create a result xmldocument.
        /// </summary>
        /// <param name="sourceXml"></param>
        /// <returns></returns>
        public static XmlDocument CreateESBResult(XmlDocument sourceXml)
        {
            var esbEnvelope = ESBEnvelopeEntity.FromXML(sourceXml);

            return esbEnvelope.ToResultXml();
        }

        /// <summary>
        /// Get message body.
        /// </summary>
        /// <param name="sourceXml"></param>
        /// <returns></returns>
        public static XmlDocument GetMsgBody(XmlDocument sourceXml)
        {
            //var msgBody = ESBEnvelopeEntity.FromXML(sourceXml).MsgBody;

            //var result = new XmlDocument();

            //try
            //{
            //    result.LoadXml(msgBody);
            //}
            //catch
            //{
            //}

            //return result;

            return ESBEnvelopeEntity.FromXML(sourceXml).MsgBodyXml;
        }

        /// <summary>
        /// Create a unknowed exception message.
        /// </summary>
        /// <param name="errorMessage"></param>
        /// <returns></returns>
        public static XmlDocument CreateCustomExceptionXML(string errorCode, string errorMessage, XmlDocument requestXml)
        {
            ESBEnvelopeEntity entity = ESBEnvelopeEntity.CreateWithHeader();

            ModifyResponseHeader(requestXml, entity);

            entity.ESBRspCode = errorCode;
            entity.ESBRspDec = XMLEncode(errorMessage);
            entity.MsgBody = "<error>Please check the ESBHeader/ESBRspDec.</error>";
            return entity.ToResultXml();
        }

        /// <summary>
        /// Force transfer message.
        /// </summary>
        /// <param name="sourceXml"></param>
        /// <returns></returns>
        public static XmlDocument ForceTransferMsg(XmlDocument sourceXml)
        {
            return sourceXml;
        }

        /// <summary>
        /// Modify response header, just like: CorrID, ReceiverID, SenderID, SrvOpName.
        /// </summary>
        /// <param name="requestXml"></param>
        /// <param name="entity"></param>
        private static void ModifyResponseHeader(XmlDocument requestXml, ESBEnvelopeEntity entity)
        {
            var requestEntity = ESBEnvelopeEntity.FromXML(requestXml);
            entity.CorrID = requestEntity.CorrID;
            entity.SenderID = requestEntity.ReceiverID;
            entity.ReceiverID = requestEntity.SenderID;
            entity.SrvOpName = requestEntity.SrvOpName;
        }

        /// <summary>
        /// Create a unknowed exception message.
        /// </summary>
        /// <param name="errorMessage"></param>
        /// <returns></returns>
        public static XmlDocument CreateCustomExceptionXML(string errorCode, string errorMessage, XmlDocument requestXml, XmlDocument laRcvMsg)
        {
            ESBEnvelopeEntity entity = ESBEnvelopeEntity.CreateWithHeader();

            ModifyResponseHeader(requestXml, entity);

            entity.ESBRspCode = errorCode;
            entity.ESBRspDec = errorMessage;

            entity.MsgBody = laRcvMsg.OuterXml;
            return entity.ToResultXml();
        }

        #region aura
        /// <summary>
        /// Transfer for aura
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static XmlDocument TransferForAura(XmlDocument xml)
        {
            var resultXml = new XmlDocument();
            resultXml.LoadXml("<underwrite xmlns=\"urn:AuraWebService\"><inputXML></inputXML></underwrite>");
            var inputXML = resultXml.FirstChild.FirstChild;
            inputXML.InnerXml = string.Format("<![CDATA[{0}]]>", xml.InnerXml);

            return resultXml;
        }

        /// <summary>
        /// GetXmlFromAuraResponse
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static XmlDocument GetXmlFromAuraResponse(XmlDocument xml)
        {
            var resultXml = new XmlDocument();

            for (int i = 0; i < xml.ChildNodes.Count; i++)
            {
                var node = xml.ChildNodes[i];
                if (node.LocalName == "Envelope")
                {
                    var outputXml = node.FirstChild.FirstChild.FirstChild;
                    var decodeXml = XMLDecode(outputXml.InnerXml);
                    resultXml.LoadXml(decodeXml);

                    return resultXml;
                }
            }

            return resultXml;
        }

        /// <summary>
        /// Get xml from la response for aura
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static XmlDocument GetXmlFromLAResponseForAURA(XmlDocument xml)
        {
            var resultXml = new XmlDocument();

            for (int i = 0; i < xml.ChildNodes.Count; i++)
            {
                var node = xml.ChildNodes[i];
                if (node.LocalName == "Envelope")
                {
                    var outputXml = node.FirstChild;
                    var decodeXml = XMLDecode(outputXml.InnerXml);
                    resultXml.LoadXml(decodeXml);

                    return resultXml;
                }
            }

            return resultXml;
        }

        private static string XMLDecode(string sourceStr)
        {
            return sourceStr.Replace("&amp;", "&")
            .Replace("&lt;", "<")
            .Replace("&gt;", ">")
            .Replace("&quot;", "\"")
            .Replace("&apos;", "'");
        }

        private static string XMLEncode(string sourceStr)
        {
            if (string.IsNullOrEmpty(sourceStr)) return sourceStr;

            return sourceStr.Replace("&", "&amp;")
            .Replace("<", "&lt;")
            .Replace(">", "&gt;")
            .Replace("\"", "&quot;")
            .Replace("'", "&apos;");
        }

        #endregion

        #region test
        /// <summary>
        /// Create Sample XML Message
        /// </summary>
        /// <returns></returns>
        public static XmlDocument CreateAuraSuccessReturnSampleXML()
        {
            XmlDocument document = new XmlDocument();
            document.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body><underwriteResponse xmlns=\"urn:AuraWebService\"><underwriteReturn>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;&lt;ProcessMessage xmlns=&quot;http://eai.metlife.com/&quot;&gt;&lt;ESBHeader&gt;&lt;ESBHdVer&gt;20120606_1.0&lt;/ESBHdVer&gt;&lt;SrvDate&gt;2012/10/21&lt;/SrvDate&gt;&lt;SrvTime&gt;10:10:28.10281028&lt;/SrvTime&gt;&lt;SenderID&gt;AURA&lt;/SenderID&gt;&lt;ReceiverID&gt;MTS&lt;/ReceiverID&gt;&lt;SrvOpName&gt;AuraService&lt;/SrvOpName&gt;&lt;SrvOpVer&gt;20120606_1.1&lt;/SrvOpVer&gt;&lt;MsgID&gt;250D75A2-228C-43D3-AF70-91130A9FCBD7&lt;/MsgID&gt;&lt;CorrID&gt;665F45D9-BA06-4AC9-A25D-95861E8B686D&lt;/CorrID&gt;&lt;ESBRspCode&gt;0&lt;/ESBRspCode&gt;&lt;ESBRspDec/&gt;&lt;ResField1/&gt;&lt;ResField2/&gt;&lt;ResField3/&gt;&lt;ResField4/&gt;&lt;ResField5/&gt;&lt;/ESBHeader&gt;&lt;MsgBody&gt;&lt;XML&gt;&lt;AURATX&gt;&lt;APPNum&gt;pri00331213456789&lt;/APPNum&gt;&lt;Chdrnum&gt;12000001&lt;/Chdrnum&gt;&lt;ApplicationDecision&gt;RUW&lt;/ApplicationDecision&gt;&lt;Insureds&gt;&lt;Insured&gt;&lt;UniqueID&gt;CUSTOMID13&lt;/UniqueID&gt;&lt;Name&gt;&#x5F20;&#x4E09;&lt;/Name&gt;&lt;AcuRiskAmount/&gt;&lt;OverallDecisions&gt;&lt;Decision&gt;&lt;Product&gt;AB0010&lt;/Product&gt;&lt;UnderwritingDecision&gt;&lt;DecisionCode&gt;RUW&lt;/DecisionCode&gt;&lt;ReasonCode&gt;A15&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x6295;&#x4FDD;&#x4EBA;&#x804C;&#x4E1A;&#x4EE3;&#x7801;&#x586B;&#x5199;&#x6709;&#x8BEF;&lt;/ReasonDescription&gt;&lt;ReasonCode&gt;A33&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x88AB;&#x4FDD;&#x9669;&#x4EBA;&#x804C;&#x4E1A;&#x4EE3;&#x7801;&#x586B;&#x5199;&#x6709;&#x8BEF;&lt;/ReasonDescription&gt;&lt;ReasonCode&gt;A44&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x8EAB;&#x6545;&#x53D7;&#x76CA;&#x4EBA;&#x53D7;&#x76CA;&#x6BD4;&#x4F8B;&#x672A;&#x586B;&#x5199;&lt;/ReasonDescription&gt;&lt;/UnderwritingDecision&gt;&lt;/Decision&gt;&lt;Decision&gt;&lt;Product&gt;JCI101&lt;/Product&gt;&lt;UnderwritingDecision&gt;&lt;DecisionCode&gt;RUW&lt;/DecisionCode&gt;&lt;ReasonCode&gt;A15&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x6295;&#x4FDD;&#x4EBA;&#x804C;&#x4E1A;&#x4EE3;&#x7801;&#x586B;&#x5199;&#x6709;&#x8BEF;&lt;/ReasonDescription&gt;&lt;ReasonCode&gt;A33&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x88AB;&#x4FDD;&#x9669;&#x4EBA;&#x804C;&#x4E1A;&#x4EE3;&#x7801;&#x586B;&#x5199;&#x6709;&#x8BEF;&lt;/ReasonDescription&gt;&lt;ReasonCode&gt;A44&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x8EAB;&#x6545;&#x53D7;&#x76CA;&#x4EBA;&#x53D7;&#x76CA;&#x6BD4;&#x4F8B;&#x672A;&#x586B;&#x5199;&lt;/ReasonDescription&gt;&lt;/UnderwritingDecision&gt;&lt;/Decision&gt;&lt;Decision&gt;&lt;Product&gt;HOLDERCOV01&lt;/Product&gt;&lt;UnderwritingDecision&gt;&lt;DecisionCode&gt;RUW&lt;/DecisionCode&gt;&lt;ReasonCode&gt;A15&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x6295;&#x4FDD;&#x4EBA;&#x804C;&#x4E1A;&#x4EE3;&#x7801;&#x586B;&#x5199;&#x6709;&#x8BEF;&lt;/ReasonDescription&gt;&lt;ReasonCode&gt;A33&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x88AB;&#x4FDD;&#x9669;&#x4EBA;&#x804C;&#x4E1A;&#x4EE3;&#x7801;&#x586B;&#x5199;&#x6709;&#x8BEF;&lt;/ReasonDescription&gt;&lt;ReasonCode&gt;A44&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x8EAB;&#x6545;&#x53D7;&#x76CA;&#x4EBA;&#x53D7;&#x76CA;&#x6BD4;&#x4F8B;&#x672A;&#x586B;&#x5199;&lt;/ReasonDescription&gt;&lt;/UnderwritingDecision&gt;&lt;/Decision&gt;&lt;Decision&gt;&lt;Product&gt;INSUREDCOV01&lt;/Product&gt;&lt;UnderwritingDecision&gt;&lt;DecisionCode&gt;RUW&lt;/DecisionCode&gt;&lt;ReasonCode&gt;A15&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x6295;&#x4FDD;&#x4EBA;&#x804C;&#x4E1A;&#x4EE3;&#x7801;&#x586B;&#x5199;&#x6709;&#x8BEF;&lt;/ReasonDescription&gt;&lt;ReasonCode&gt;A33&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x88AB;&#x4FDD;&#x9669;&#x4EBA;&#x804C;&#x4E1A;&#x4EE3;&#x7801;&#x586B;&#x5199;&#x6709;&#x8BEF;&lt;/ReasonDescription&gt;&lt;ReasonCode&gt;A44&lt;/ReasonCode&gt;&lt;ReasonDescription&gt;&#x8EAB;&#x6545;&#x53D7;&#x76CA;&#x4EBA;&#x53D7;&#x76CA;&#x6BD4;&#x4F8B;&#x672A;&#x586B;&#x5199;&lt;/ReasonDescription&gt;&lt;/UnderwritingDecision&gt;&lt;/Decision&gt;&lt;/OverallDecisions&gt;&lt;/Insured&gt;&lt;/Insureds&gt;&lt;ReturnCode/&gt;&lt;ReturnDesc/&gt;&lt;/AURATX&gt;&lt;/XML&gt;&lt;/MsgBody&gt;&lt;/ProcessMessage&gt;</underwriteReturn></underwriteResponse></soapenv:Body></soapenv:Envelope>");
            return document;
        }

        /// <summary>
        /// Create Sample chinese XML Message
        /// </summary>
        /// <returns></returns>
        public static XmlDocument CreateSampleXMLWithCn()
        {
            XmlDocument document = new XmlDocument();
            document.LoadXml("<ns0:ESBEnvelope xmlns:ns0=\"http://MetLifeEAI.EAISchema\">  <ESBHeader>    <ESBHdVer>ESBHdVer_0</ESBHdVer>    <SrvDate>1999-05-31</SrvDate>    <SrvTime>13:20:00.000-05:00</SrvTime>    <SenderID>SenderID_0</SenderID>    <ReceiverID>ReceiverID_0</ReceiverID>    <SrvOpName>SrvOpName_0</SrvOpName>    <SrvOpVer>SrvOpVer_0</SrvOpVer>    <MsgID>MsgID_0</MsgID>    <CorrID>CorrID_0</CorrID>    <ESBRspCode>ESBRspCode_0</ESBRspCode>    <ESBRspDec>成功</ESBRspDec>    <ResField1>ResField1_0</ResField1>    <ResField2>ResField2_0</ResField2>    <ResField3>ResField3_0</ResField3>    <ResField4>ResField4_0</ResField4>    <ResField5>ResField5_0</ResField5>  </ESBHeader>    <MsgBody><Sample>中文</Sample></MsgBody></ns0:ESBEnvelope>");

            return document;
        }

        /// <summary>
        /// Create sample XML Message
        /// </summary>
        /// <param name="sourceXml"></param>
        /// <returns></returns>
        public static XmlDocument CreateSampleXML(XmlDocument sourceXml)
        {
            var entity = ESBEnvelopeEntity.FromXML(sourceXml);
            entity.MsgBody = "<Sample>I'm from EAI.</Sample>";
            return entity.ToXml();
        }

        #endregion
    }
}
